iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0
Modern Web

為期 N 天的 react 小冒險系列 第 17

react hook 內的快樂好朋友-useRef-day17

  • 分享至 

  • xImage
  •  

來介紹一下最後一個好朋友 useRef
基本上 state 的更新會促成每一次的 re-render
reference 則是更新後並不會造成 re-render 發生

useRef 作用

  • 每一次 render 間保存值
  • 儲存可被變更的值,但該值的變更並不會造成 component re-render
  • 直接存取(access) DOM 元素

infinite loop 無限迴圈的錯誤

假設說想獲取 component 被 render 了幾次..直覺下可能會這樣寫

SomeComp.js(請不要真的照這樣寫XD)

import { useState, useRef, useEffect } from 'react'

function UseRef() {
  const [name, setName] = useState('')
  const [renderTimes, setRenderTimes] = useState(0)

  function handleNameInput(e) {
    setName(e.target.value)
  }

  useEffect(()=>{
    setRenderTimes((renderTimes)=>renderTimes+1 );
  })

  return (
    <>
      <input type='text' onChange={handleNameInput} />
      <p>name:{name}</p>
      <p>{renderTimes}</p>
    </>
  )
}

export default UseRef

隨著 useEffect 的執行,renderTimes 被更新,而 renderTimes 的更新又造成整個 component re-render...以至於變成無限迴圈的狀態

這時候便輪到 useRef 出場了~

import { useState, useRef, useEffect } from 'react'

function UseRef() {
  const [name, setName] = useState('')
  // useRef 只會 return ㄧ個叫 current 的 object
  const renderTimes = useRef(0)

  function handleNameInput(e) {
    setName(e.target.value)
  }

  useEffect(()=>{
    renderTimes.current = renderTimes.current+1
  })

  return (
    <>
      <input type='text' onChange={handleNameInput} />
      <p>name:{name}</p>
      <p>{renderTimes.current}</p>
    </>
  )
}

export default UseRef

useRef只會回傳一個名叫 current 的 object
這時候就可以獲取到 renderTimes.current 的值,而該值不會造成整個 component re-render

直接 access DOM 元素

使用 useRef 的場合

參考資料

https://blog.openreplay.com/build-a-react-timer-application-with-useref


上一篇
react hook 內的快樂好朋友-useCallback / useMemo-day16
下一篇
用 react hook 寫一個簡易計算機吧-上-day18
系列文
為期 N 天的 react 小冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言